<?php

namespace App\Trip\Orders\BookOrders\Plane\PriceDetails;

use App\Models\Plane\PlaneOrderPassengers\PlaneOrderPassenger;
use App\Models\Plane\PlaneOrders\PlaneOrder;
use App\Models\Trip\TripOrderCosts\TripOrderCost;
use App\Trip\Orders\TripNo;
use App\Trip\Passengers\Passengers;
use Exception;
use Illuminate\Support\Str;

class ChangePlanePriceDetails
{
    private array      $passengers;
    private PlaneOrder $origin_order_info;
    private array      $price_details;
    /**
     * @var float
     */
    private float $order_amount;
    private float $origin_order_need_refund_amount = 0;
    private float $total_construction_fee          = 0;
    private float $total_fuel_fee                  = 0;
    /**
     * 是否 to_be_confirm
     * @var bool
     */
    private bool  $is_tbc            = false;
    private float $total_upgrade_fee = 0;

    /**
     * @throws Exception
     */
    public function __construct(PlaneOrder $origin_order_info, array $passengers)
    {
        $this->passengers        = $passengers;
        $this->origin_order_info = $origin_order_info;
        $this->buildPriceDetails();
    }

    /**
     *
     * @throws Exception
     */
    private function buildPriceDetails(): void
    {
        $passengers             = $this->passengers;
        $origin_passengers      = $this->origin_order_info->getPassengers();
        $name                   = TripNo::TRIP_NO_DESC[$this->origin_order_info->getTripNo()];
        $details                = [];
        $total_price            = 0;
        $total_construction_fee = 0;
        $total_fuel_fee         = 0;
        $total_upgrade_fee      = 0;
        /**
         * 乘客改签手续费
         * 票价差
         * 燃油差价
         * 基建差价
         * @var PlaneOrderPassenger $origin_order_passenger
         */
        foreach ($passengers as $key => $passenger) {
            $passenger_type = $passenger['passenger_type'];
            if (!isset($passenger['origin_passenger'])) {
                $origin_passenger                     = $origin_passengers
                    ->where('passenger_id', $passenger['passenger_id'])
                    ->where('sequence', $passenger['sequence'])
                    ->firstWhere('passenger_type', $passenger_type);
                $passengers[$key]['origin_passenger'] = $passenger['origin_passenger'] = $origin_passenger;
            }
            $origin_order_passenger                       = $passenger['origin_passenger'];
            $passenger_type_name                          = Str::replace("票", "", Passengers::PASSENGER_TYPE_DESC[$passenger_type]);
            $passengers[$key]['origin_order_need_refund'] = 0;
            $passengers[$key]['change_ticket_loss']       = 0;
            $passengers[$key]['provider_price_state']     = 1;// 价格待确认 0  ,默认 已确认 1
            /*****改签手续费****/
            $total_construction_fee += $passenger['construct_fee'] ?? 0;
            $total_fuel_fee         += $passenger['fuel_fee'] ?? 0;
            $change_fee_key         = "change_fee:".$passenger_type_name;
            if ($passenger['change_fee'] >= 0) {
                if (!isset($details[$change_fee_key])) {
                    $details[$change_fee_key] = [
                        "type"        => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,//改签手续费
                        "parent_type" => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                        "name"        => $passenger_type_name.'改签手续费',
                        "name_uy"     => trans2uy($passenger_type_name.'改签手续费'),
                        "price"       => $passenger['upgrade_fee'] >= 0 ? $passenger['change_fee'] + $passenger['upgrade_fee'] : -1,
                        "count"       => 1,
                    ];
                } else {
                    $details[$change_fee_key]["count"]++;
                }
                $total_price                         += $passenger['change_fee'];
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                    "name"        => '改签手续费',
                    "price"       => $passengers[$key]['change_fee'],
                ];
            } else {
                // 改签费待确认
                $this->is_tbc = true;
                if (!isset($details[$change_fee_key])) {
                    $details[$change_fee_key] = [
                        "type"          => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,//改签手续费
                        "parent_type"   => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                        "name"          => $passenger_type_name.'改签手续费',
                        "name_uy"       => trans2uy($passenger_type_name.'改签手续费'),
                        "price"         => -1,
                        "count"         => 1,
                        "confirm_state" => TripOrderCost::COST_STATE_TBC,
                    ];
                } else {
                    $details[$change_fee_key]["count"]++;
                }

                $passengers[$key]['price_details'][]      = [
                    "type"          => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                    "parent_type"   => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                    "name"          => '改签手续费',
                    "price"         => $passengers[$key]['change_fee'],
                    "confirm_state" => TripOrderCost::COST_STATE_TBC,
                ];
                $passengers[$key]['change_fee']           = 0;
                $passengers[$key]['total_price']          = 0;
                $passengers[$key]['provider_price_state'] = 0;
            }
            /********升舱费 合并计入到 改签费*********/
            if ($passenger['upgrade_fee'] >= 0) {
                // 合并计入到 改签费
                $total_price                         += $passenger['upgrade_fee'];
                $total_upgrade_fee                   += $passenger['upgrade_fee'];
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_UPGRADE_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_UPGRADE_FEE,
                    "name"        => '升舱费',
                    "price"       => $passengers[$key]['upgrade_fee'],
                ];

            } else {
                // 改签费待确认 
                $this->is_tbc                              = true;
                $details[$change_fee_key]['confirm_state'] = 0;
                $passengers[$key]['price_details'][]       = [
                    "type"          => TripOrderCost::COST_TYPE_PLANE_CHANGE_UPGRADE_FEE,
                    "parent_type"   => TripOrderCost::COST_TYPE_PLANE_CHANGE_UPGRADE_FEE,
                    "name"          => '升舱费',
                    "price"         => $passengers[$key]['upgrade_fee'],
                    "confirm_state" => TripOrderCost::COST_STATE_TBC,
                ];
                $passengers[$key]['upgrade_fee']           = 0;
                $passengers[$key]['total_price']           = 0;
                $passengers[$key]['provider_price_state']  = 0;
            }


            /********机票差价*********/
            $price_diff_key = "ticket_price_diff:".$passenger_type_name;
            if ($passenger['ticket_price_diff'] > 0) {
                if (!isset($details[$price_diff_key])) {
                    $details[$price_diff_key] = [
                        "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_TICKET,//机票差价
                        "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_TICKET,
                        "name"        => $passenger_type_name.'改签票差价',
                        "name_uy"     => trans2uy($passenger_type_name.'改签票差价'),
                        "price"       => $passenger['ticket_price_diff'],
                        "count"       => 1,
                    ];
                } else {
                    $details[$price_diff_key]["count"]++;
                }
                $total_price                         += $passenger['ticket_price_diff'];
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_TICKET,
                    "parent_type" => TripOrderCost::COST_TYPE_CHANGE_SERVICE_FEE,
                    "name"        => '改签票差价',
                    "price"       => $passengers[$key]['ticket_price_diff'],
                ];
            }
            /********基建差价*********/
            $construction_fee_diff_key = "construction_fee_diff:".$passenger_type_name;
            if ($passenger['construction_fee_diff'] > 0) {
                if (!isset($details[$construction_fee_diff_key])) {
                    $details[$construction_fee_diff_key] = [
                        "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_CONSTRUCTION_FEE,//机建费差价
                        "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_CONSTRUCTION_FEE,
                        "name"        => $passenger_type_name.'机建费差价',
                        "name_uy"     => trans2uy($passenger_type_name.'机建费差价'),
                        "price"       => $passenger['construction_fee_diff'],
                        "count"       => 1,
                    ];
                } else {
                    $details[$construction_fee_diff_key]["count"]++;
                }
                $total_price                         += $passenger['construction_fee_diff'];
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_CONSTRUCTION_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_CONSTRUCTION_FEE,
                    "name"        => '机建费差价',
                    "price"       => $passengers[$key]['construction_fee_diff'],
                ];
            }
            /********燃油费差价*********/
            $fuel_fee_diff_key = "fuel_fee_diff:".$passenger_type_name;
            if ($passenger['fuel_fee_diff'] > 0) {
                if (!isset($details[$fuel_fee_diff_key])) {
                    $details[$fuel_fee_diff_key] = [
                        "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_FUEL_FEE,//燃油费差价
                        "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_FUEL_FEE,
                        "name"        => $passenger_type_name.'燃油费差价',
                        "name_uy"     => trans2uy($passenger_type_name.'燃油费差价'),
                        "price"       => $passenger['fuel_fee_diff'],
                        "count"       => 1,
                    ];
                } else {
                    $details[$fuel_fee_diff_key]["count"]++;
                }
                $total_price                         += $passenger['fuel_fee_diff'];
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_FUEL_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_PLANE_CHANGE_DIFF_FUEL_FEE,
                    "name"        => '燃油费差价',
                    "price"       => $passengers[$key]['fuel_fee_diff'],
                ];
            }

            // 保存原票票价
            $passengers[$key]['origin_ticket_price'] = $origin_order_passenger->getTicketPrice();
        }

        if (empty($passengers)) {
            throw new Exception('暂无可改签的乘客');
        }
        $this->passengers = $passengers;
        if ($this->is_tbc) {
            $total_price = -1;
        }
        $this->price_details = [
            'name'        => $name,
            'name_uy'     => trans2uy($name),
            'total_price' => $total_price,
            'details'     => collect($details)->sortBy('type')->values()->toArray(),
        ];

        $this->order_amount           = $total_price;
        $this->total_construction_fee = $total_construction_fee;
        $this->total_fuel_fee         = $total_fuel_fee;
        $this->total_upgrade_fee      = $total_upgrade_fee;
    }

    public function getPassengers(): array
    {
        return $this->passengers;
    }

    public function getPriceDetails(): array
    {
        return $this->price_details;
    }

    /**
     * 升舱费
     * @return float|int
     */
    public function getTotalUpgradeFee(): float|int
    {
        return $this->total_upgrade_fee;
    }

    /**
     * 机建费
     * @return float|int
     */
    public function getTotalConstructionFee(): float|int
    {
        return $this->total_construction_fee;
    }

    /**
     * 燃油费
     * @return float|int
     */
    public function getTotalFuelFee(): float|int
    {
        return $this->total_fuel_fee;
    }

    /**
     *
     * @throws Exception
     */
    public function calcReceivable(): float
    {
        return $this->getOrderAmount();
    }


    public function getOrderAmount(): float
    {
        if ($this->is_tbc) {
            return 0;
        }
        return $this->order_amount;
    }

    /**
     * 供应商价格是否确认
     * @return int
     */
    public function isConfirm(): int
    {
        // 待确认 0 已确认 1
        return $this->is_tbc ? 0 : 1;
    }

    /**
     * 原订单需退款金额
     *
     * @throws Exception
     */
    public function calcOriginNeedRefundAmount(): float
    {
        return $this->origin_order_need_refund_amount;

    }

    public function getServiceFee(): float
    {
        return 0;
    }
}